package application.net;

import application.anno.Injection;
import application.anno.PostParam;
import lombok.Data;
import okhttp3.*;

import java.io.IOException;
import java.lang.reflect.Field;

@Injection(staticMethodName = "getInstance")
public class HttpOperation {

    @Data
    public static class NetResult {

        private String url;

        private Object params;
    }

    protected OkHttpClient okHttpClient;

    private static HttpOperation httpOperation = new HttpOperation();

    private HttpOperation() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        okHttpClient = builder.build();
    }

    public static HttpOperation getInstance() {
        if (httpOperation == null) {
            httpOperation = new HttpOperation();
        }
        return httpOperation;
    }

    public OkHttpClient.Builder getOkHttpClientBuilder() {
        return this.okHttpClient.newBuilder();
    }

    public void updateOkHttpClient(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }

    public Response syncGet(String url) throws IOException {
        Request request = new Request.Builder().url(url).build();
        Response response = okHttpClient.newCall(request).execute();
        return response;
    }

    public void asyncGet(NetResult netResult, Callback callback) {
        String url = netResult.url;
        Request request = new Request.Builder().url(url).build();
        okHttpClient.newCall(request).enqueue(callback);
    }

    public void post(NetResult netResult, Callback callBack) throws IllegalAccessException {
        String url = netResult.url;
        Object params = netResult.params;
        FormBody.Builder builder = new FormBody.Builder();
        Field[] declaredFields = params.getClass().getDeclaredFields();
        Field[] superFields = params.getClass().getSuperclass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object o = field.get(params);
            String name = field.getName();
            builder.add(name, String.valueOf(o));
        }
        for (Field field : superFields) {
            field.setAccessible(true);
            Object o = field.get(params);
            String name;
            PostParam declaredAnnotation = field.getDeclaredAnnotation(PostParam.class);
            if (declaredAnnotation != null) {
                name = declaredAnnotation.postName();
            } else {
                name = field.getName();
            }
            builder.add(name, String.valueOf(o));
        }
        FormBody formBody = builder.build();
        Request request = new Request.Builder().url(url).post(formBody).build();
        okHttpClient.newCall(request).enqueue(callBack);
    }
}
